import os.path
import ftplib
import pymysql
'''
从ftp下载数据文件和filelist文件，
优先下载filelist文件，在根据filelist文件对应的文件名称下载文件
'''

class FTPUtil():
    ftp = ftplib.FTP()

    def __init__(self, host='', port=21):
        # 登录ftp的主机名称的端口号
        if host == '':
            pass
        else:
            self.ftp.connect(host, port)
            print('instance sucessful !')

    def Login(self, user, passwd, path):
        # 登录ftp的用户名和密码
        self.ftp.login(user, passwd)
        self.ftp.cwd(path)
        print('ftp login sucessful !')

    def DownLoadFile(self, RemoteFile, LocalFile):
        file_handler = open(LocalFile, 'wb')
        # 以二进制写本地文件，本地文件名称LocalFile
        self.ftp.retrbinary("RETR %s" % (RemoteFile), file_handler.write)
        file_handler.close()
        FileName = os.path.basename(LocalFile)
        print(FileName + ' download sucessful !')
        return True

    def DownLoadDir(self, LocalDir, RemoteDir):
        # 下载整个文件夹中的文件到指定文件中
        if os.path.isdir(LocalDir) == False:
            os.makedirs(LocalDir)
        self.ftp.cwd(RemoteDir)

        RemoteNames = self.ftp.nlst()
        for RemoteName in RemoteNames:
            if RemoteName.endswith('.txt'):
                # 拼接目录和文件名称
                LocalFile = os.path.join(LocalDir, RemoteName)
                print(LocalFile)
                self.DownLoadFile(LocalFile, RemoteName)
                print(LocalFile, 'download sucessful')
            else:
                pass
        return

    def CheckFileList(self, LocalFile, FileList):
        # 校验filelist文件正确性，通过获取文件大小和行数与filelist文件比较，相等则校验通过
        # filelist文件大小  序号|文件名称|文件大小|文件行数
        if LocalFile.startswith('DC_FILELIST'):
            size = os.path.getsize(LocalFile)
            if size > 0:
                return True

        with open(LocalFile) as f_obj:
            filelines = f_obj.readlines()
            file_count = len(filelines)
        file_size = os.path.getsize(LocalFile)

        print('file_count is ', file_count)
        print('file_size  is ', file_size)

        with open(FileList) as f_obj:
            while True:
                line = f_obj.readline()
                line = line.strip()
                if not line:
                    break

                listline = line.split('|')
                filename = listline[1]
                filelist_size = 0
                filelist_count = 0
                file = os.path.basename(LocalFile)
                if filename == file:
                    filelist_size = listline[2]
                    filelist_count = listline[3]
                else:
                    continue
            print('filelist_size is ', filelist_size)
            print('filelist_count  is ', filelist_count)
        if file_count == int(filelist_count):  # and file_size == filelist_size:
            return True
        else:
            return False

    def CheckResult(self, LocalFile, flag):
        if flag == False:
            print(LocalFile + ' DownLoad fail or check fail!')
        else:
            print(LocalFile + ' DownLoad check sucessful')

    def Close(self):
        self.ftp.quit()

    def get_connect(self):
        # 四个参数依次是服务器地址，用户名，密码，数据库名称
        dbconn = pymysql.connect("localhost", "root", "123456", "test")
        return dbconn

    def get_cursor(self, dbconn):
        if dbconn is not None:
            return dbconn.cursor()

    def get_ftp(self):
        # 获取文件对应的ftp配置信息
        conn = self.get_connect()
        cu = self.get_cursor(conn)
        # 每次取filelist中的一条数据下载
        select_sql = "select FILENAME,FTPIP,FTPUSER,PASSWD,FILEPATH,FILELIST,DOWNFLAG,DATE \
        from FILE_DBF_LIST WHERE DOWNFLAG = '0' and date = current_date \
        limit 1"
        cu.execute(select_sql)
        tup = cu.fetchone()
        return tup

    def update_download(self, LocalFile):
        # 文件下载之后，更新下载标识为已下载
        conn = self.get_connect()
        cu = self.get_cursor(conn)
        update_sql = "update FILE_DBF_LIST set DOWNFLAG  = '1' WHERE DOWNFLAG = '0' and FILENAME = %s "
        cu.execute(update_sql, LocalFile)
        conn.commit()
        print(LocalFile + '下载标识更新成功！')
        return

    def update_dowlflag(self):
        # 在当天所有的下载任务全部完成之后，将所有任务全部重置为未下载，未明天的数据下载做准备，同时数据表切日
        conn = self.get_connect()
        cu = self.get_cursor(conn)
        update_sql = "update FILE_DBF_LIST set DOWNFLAG  = '0' and date = date_add(date,interval 1 day)  WHERE DOWNFLAG = '1' "
        select_sql = "select count(*) from FILE_DBF_LIST WHERE DOWNFLAG = '0' and date = date_add(current_date,interval 1 day) "
        select_count = "select count(*) from FILE_DBF_LIST "
        cu.execute(select_sql)
        select_count1 = cu.fetchone()
        cu.execute(select_count)
        select_count2 = cu.fetchone()
        if select_count1 == select_count2:
            cu.execute(update_sql)
            conn.commit()
            print('下载标识重置成功，切日成功！')
        return


if __name__ == '__main__':
    ftp = FTPUtil()
    tup = ftp.get_ftp()
    if tup:
        ftp = FTPUtil(tup[1])
        ftp.Login(tup[2], tup[3], tup[4])
        #  先下载filelist文件，filelist文件下载之后获取该filelist对应的文件
        flag = ftp.DownLoadFile(tup[5], tup[5])
        # filelist文件下载成功,之后在下载filelist文件对应的文件
        if flag == True:
            ftp.DownLoadFile(tup[0], tup[0])
            flag1 = ftp.CheckFileList(tup[0], tup[5])
            # 如果文件下载并校验filelist文件成功，则返回成功状态，并更新状态码
            if flag1 == True:
                ftp.CheckResult(tup[0], flag1)
                ftp.update_download(tup[0])
        ftp.Close()
    else:
        # 数据文件下载完成，切日
        ftp.update_dowlflag()
        print('暂无下载任务')